package com.example.libpro.DAO;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.example.libpro.DBEntity.BorrowRecordEntity;
import com.example.libpro.DBEntity.DBHelper;
import com.example.libpro.DBEntity.DataBaseContext;

import java.util.ArrayList;
import java.util.List;

/**
 * 图书管理系统借阅记录数据访问类（DAO）
 * 作用：1. 封装"borrow_record"表的所有CRUD操作，直接对接DBHelper的数据库实例；
 * 2. 实现《安卓设计报告.docx》中"借书业务流程-记录借阅"、"还书业务流程-记录归还"、"管理员·借还查询-查看借阅记录/逾期列表"的底层数据操作；
 * 3. 为服务层（BorrowReturnService）提供借阅记录访问接口，支持借还审核状态更新（报告"管理员·借还审核"）。
 * 关联实体：BorrowRecordEntity（映射"borrow_record"表）
 * 依赖：DBHelper（获取SQLite数据库实例）、Android Context（初始化DBHelper）
 * 业务适配：支持逾期记录筛选（报告"还书业务流程-违规处理"）、审核状态查询（报告"管理员·借还审核"）
 */
public class BorrowRecordDAO {
    private final DBHelper dbHelper;

    // 构造方法：初始化DBHelper
    /**
     * BorrowRecordDAO构造方法
     * @param context Android上下文对象，用于创建DBHelper实例
     * 功能：建立与SQLite数据库的连接，为借阅记录CRUD操作提供基础
     */
    public BorrowRecordDAO(Context context) {
        DataBaseContext dbContext = new DataBaseContext(context);
        this.dbHelper = new DBHelper(dbContext);
    }

    // 1. 新增借阅记录（对应报告"借书业务流程-借书→记录借阅"）
    /**
     * 新增借阅记录（插入"borrow_record"表）
     * @param recordEntity 借阅记录实体（含用户ID、图书ID、借阅时间、应还时间、审核状态）
     * @return boolean 操作结果：true=新增成功，false=新增失败
     * 业务适配：符合报告"读者提交借阅申请→管理员审核→借书→更新记录"流程；
     * 初始状态：1. 借阅状态（borrowStatus）=0（未还）；2. 审核状态（auditStatus）=0（待审核）；3. 实际归还时间（actualReturnTime）=null
     */
    public boolean insertBorrowRecord(BorrowRecordEntity recordEntity) {
        SQLiteDatabase db = null;
        try {
            // 基础数据校验
            if (recordEntity.getUserId() == null || recordEntity.getBookId() == null ||
                    recordEntity.getBorrowTime() == null || recordEntity.getDueTime() == null) {
                return false;
            }

            db = dbHelper.getWritableDB();
            ContentValues values = new ContentValues();
            values.put("user_id", recordEntity.getUserId());
            values.put("book_id", recordEntity.getBookId());
            values.put("borrow_time", recordEntity.getBorrowTime());
            values.put("due_time", recordEntity.getDueTime());
            values.put("actual_return_time", recordEntity.getActualReturnTime()); // 初始为null
            values.put("borrow_status", 0); // 0=未还（报告中未还状态）
            values.put("audit_status", recordEntity.getAuditStatus() != null ? recordEntity.getAuditStatus() : 0); // 默认待审核

            long rowId = db.insert("borrow_record", null, values);
            return rowId != -1;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 2. 更新借阅记录（对应报告"还书业务流程-还书→更新记录"、"管理员·借还审核"）
    /**
     * 更新借阅记录（如还书时间、借阅状态、审核状态）
     * @param recordEntity 借阅记录实体（需含borrowId，其他属性为待修改值）
     * @return boolean 操作结果：true=更新成功，false=更新失败（如记录不存在）
     * 业务适配：1. 还书时：更新实际归还时间（actualReturnTime）、借阅状态（1=已还/2=逾期）；2. 审核时：更新审核状态（1=已通过/2=已拒绝）
     */
    public boolean updateBorrowRecord(BorrowRecordEntity recordEntity) {
        SQLiteDatabase db = null;
        try {
            if (recordEntity.getBorrowId() == null) {
                return false; // 缺少借阅ID，无法更新
            }

            db = dbHelper.getWritableDB();
            ContentValues values = new ContentValues();
            // 封装待修改属性
            if (recordEntity.getActualReturnTime() != null) {
                values.put("actual_return_time", recordEntity.getActualReturnTime());
            }
            if (recordEntity.getBorrowStatus() != null) {
                values.put("borrow_status", recordEntity.getBorrowStatus());
            }
            if (recordEntity.getAuditStatus() != null) {
                values.put("audit_status", recordEntity.getAuditStatus());
            }

            String whereClause = "borrow_id = ?";
            String[] whereArgs = {String.valueOf(recordEntity.getBorrowId())};

            int affectedRows = db.update("borrow_record", values, whereClause, whereArgs);
            return affectedRows > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    // 3. 按用户ID查询借阅记录（对应报告"读者·借还-查看个人记录"）
    /**
     * 按用户ID查询该用户的所有借阅记录
     * @param userId 用户ID
     * @param borrowStatus 借阅状态（可为null：null=查所有状态，0=未还，1=已还，2=逾期）
     * @return List<BorrowRecordEntity> 该用户的借阅记录列表（无匹配时返回空列表）
     * 业务适配：符合报告"读者登录→查看个人借还记录"流程；
     * 排序逻辑：按借阅时间倒序（最新借阅在前）
     */
    public List<BorrowRecordEntity> queryBorrowRecordsByUserId(Integer userId, Integer borrowStatus) {
        List<BorrowRecordEntity> recordList = new ArrayList<>();
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            // 动态拼接查询条件
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT borrow_id, user_id, book_id, borrow_time, due_time, actual_return_time, borrow_status, audit_status ");
            sql.append("FROM borrow_record ");
            sql.append("WHERE user_id = ? ");

            List<String> argsList = new ArrayList<>();
            argsList.add(String.valueOf(userId));

            // 拼接借阅状态条件（若不为null）
            if (borrowStatus != null) {
                sql.append("AND borrow_status = ? ");
                argsList.add(String.valueOf(borrowStatus));
            }

            // 按借阅时间倒序（最新在前）
            sql.append("ORDER BY borrow_time DESC");

            String[] selectionArgs = argsList.toArray(new String[0]);
            cursor = db.rawQuery(sql.toString(), selectionArgs);

            // 封装结果集
            while (cursor.moveToNext()) {
                BorrowRecordEntity record = new BorrowRecordEntity();
                record.setBorrowId(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_id")));
                record.setUserId(cursor.getInt(cursor.getColumnIndexOrThrow("user_id")));
                record.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                record.setBorrowTime(cursor.getLong(cursor.getColumnIndexOrThrow("borrow_time")));
                record.setDueTime(cursor.getLong(cursor.getColumnIndexOrThrow("due_time")));
                // 实际归还时间可能为null（未还时），需判断
                if (!cursor.isNull(cursor.getColumnIndexOrThrow("actual_return_time"))) {
                    record.setActualReturnTime(cursor.getLong(cursor.getColumnIndexOrThrow("actual_return_time")));
                }
                record.setBorrowStatus(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_status")));
                record.setAuditStatus(cursor.getInt(cursor.getColumnIndexOrThrow("audit_status")));
                recordList.add(record);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return recordList;
    }

    // 4. 查询所有借阅记录（对应报告"管理员·借还查询-查看全部借阅记录"）
    /**
     * 查询所有借阅记录（管理员专用）
     * @param auditStatus 审核状态（可为null：null=查所有状态，0=待审核，1=已通过，2=已拒绝）
     * @return List<BorrowRecordEntity> 所有匹配的借阅记录列表（无匹配时返回空列表）
     * 业务适配：符合报告"管理员查看全部借阅记录"流程；
     * 排序逻辑：按借阅时间倒序，支持按审核状态筛选（便于管理员处理待审核申请）
     */
    public List<BorrowRecordEntity> queryAllBorrowRecords(Integer auditStatus) {
        List<BorrowRecordEntity> recordList = new ArrayList<>();
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT borrow_id, user_id, book_id, borrow_time, due_time, actual_return_time, borrow_status, audit_status ");
            sql.append("FROM borrow_record ");

            List<String> argsList = new ArrayList<>();
            // 拼接审核状态条件（若不为null）
            if (auditStatus != null) {
                sql.append("WHERE audit_status = ? ");
                argsList.add(String.valueOf(auditStatus));
            }

            sql.append("ORDER BY borrow_time DESC");
            String[] selectionArgs = argsList.toArray(new String[0]);
            cursor = db.rawQuery(sql.toString(), selectionArgs);

            while (cursor.moveToNext()) {
                BorrowRecordEntity record = new BorrowRecordEntity();
                record.setBorrowId(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_id")));
                record.setUserId(cursor.getInt(cursor.getColumnIndexOrThrow("user_id")));
                record.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                record.setBorrowTime(cursor.getLong(cursor.getColumnIndexOrThrow("borrow_time")));
                record.setDueTime(cursor.getLong(cursor.getColumnIndexOrThrow("due_time")));
                if (!cursor.isNull(cursor.getColumnIndexOrThrow("actual_return_time"))) {
                    record.setActualReturnTime(cursor.getLong(cursor.getColumnIndexOrThrow("actual_return_time")));
                }
                record.setBorrowStatus(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_status")));
                record.setAuditStatus(cursor.getInt(cursor.getColumnIndexOrThrow("audit_status")));
                recordList.add(record);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return recordList;
    }

    // 5. 查询逾期记录（对应报告"管理员·借还查询-查看逾期列表"、"借书业务流程-核验逾期"）
    /**
     * 查询所有逾期未还的借阅记录（应还时间<当前时间，且借阅状态=0=未还）
     * @return List<BorrowRecordEntity> 逾期记录列表（无逾期时返回空列表）
     * 业务适配：1. 管理员查看逾期列表（报告"管理员·借还查询"）；2. 借书时核验读者是否有逾期（报告"借书业务流程-核验未通过"）；
     * 逾期判定：应还时间（due_time）< 当前时间（System.currentTimeMillis()），且借阅状态=0（未还）
     */
    public List<BorrowRecordEntity> queryOverdueRecords() {
        List<BorrowRecordEntity> overdueList = new ArrayList<>();
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            long currentTime = System.currentTimeMillis(); // 当前时间（毫秒时间戳）
            // SQL：查询逾期未还记录（应还时间<当前时间，且未还）
            String sql = "SELECT borrow_id, user_id, book_id, borrow_time, due_time, actual_return_time, borrow_status, audit_status " +
                    "FROM borrow_record " +
                    "WHERE borrow_status = 0 " + // 未还
                    "AND due_time < ? " + // 应还时间<当前时间（逾期）
                    "ORDER BY due_time ASC"; // 按逾期时间升序（最早逾期在前）

            String[] selectionArgs = {String.valueOf(currentTime)};
            cursor = db.rawQuery(sql, selectionArgs);

            while (cursor.moveToNext()) {
                BorrowRecordEntity record = new BorrowRecordEntity();
                record.setBorrowId(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_id")));
                record.setUserId(cursor.getInt(cursor.getColumnIndexOrThrow("user_id")));
                record.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                record.setBorrowTime(cursor.getLong(cursor.getColumnIndexOrThrow("borrow_time")));
                record.setDueTime(cursor.getLong(cursor.getColumnIndexOrThrow("due_time")));
                if (!cursor.isNull(cursor.getColumnIndexOrThrow("actual_return_time"))) {
                    record.setActualReturnTime(cursor.getLong(cursor.getColumnIndexOrThrow("actual_return_time")));
                }
                record.setBorrowStatus(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_status")));
                record.setAuditStatus(cursor.getInt(cursor.getColumnIndexOrThrow("audit_status")));
                overdueList.add(record);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return overdueList;
    }

    // 6. 按审核状态查询记录（对应报告"管理员·借还审核-查询待审核申请"）
    /**
     * 按审核状态查询借阅记录（便于管理员处理审核）
     * @param auditStatus 审核状态：0=待审核，1=已通过，2=已拒绝
     * @return List<BorrowRecordEntity> 匹配审核状态的记录列表（无匹配时返回空列表）
     * 业务适配：符合报告"管理员查询全部借阅与归还申请→审核"流程；
     * 核心作用：快速筛选出待审核记录（auditStatus=0），减少管理员筛选成本
     */
    public List<BorrowRecordEntity> queryBorrowRecordsByAuditStatus(Integer auditStatus) {
        return queryAllBorrowRecords(auditStatus); // 复用queryAllBorrowRecords方法（仅按审核状态筛选）
    }

    // 辅助方法：按借阅ID查询单条记录（供审核、还书时校验）
    /**
     * 按借阅ID查询单条借阅记录（辅助方法）
     * @param borrowId 借阅ID
     * @return BorrowRecordEntity 匹配的记录实体（无匹配时返回null）
     * 功能：为updateBorrowRecord、审核操作提供前置校验（如记录是否存在、当前状态）
     */
    public BorrowRecordEntity queryBorrowRecordById(Integer borrowId) {
        SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
            db = dbHelper.getReadableDB();
            String sql = "SELECT borrow_id, user_id, book_id, borrow_time, due_time, actual_return_time, borrow_status, audit_status " +
                    "FROM borrow_record " +
                    "WHERE borrow_id = ?";
            String[] selectionArgs = {String.valueOf(borrowId)};

            cursor = db.rawQuery(sql, selectionArgs);
            if (cursor.moveToFirst()) {
                BorrowRecordEntity record = new BorrowRecordEntity();
                record.setBorrowId(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_id")));
                record.setUserId(cursor.getInt(cursor.getColumnIndexOrThrow("user_id")));
                record.setBookId(cursor.getInt(cursor.getColumnIndexOrThrow("book_id")));
                record.setBorrowTime(cursor.getLong(cursor.getColumnIndexOrThrow("borrow_time")));
                record.setDueTime(cursor.getLong(cursor.getColumnIndexOrThrow("due_time")));
                if (!cursor.isNull(cursor.getColumnIndexOrThrow("actual_return_time"))) {
                    record.setActualReturnTime(cursor.getLong(cursor.getColumnIndexOrThrow("actual_return_time")));
                }
                record.setBorrowStatus(cursor.getInt(cursor.getColumnIndexOrThrow("borrow_status")));
                record.setAuditStatus(cursor.getInt(cursor.getColumnIndexOrThrow("audit_status")));
                return record;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
            if (db != null && db.isOpen()) db.close();
        }
        return null;
    }
}